package com.ruoze.bdp.service.impl;

import com.ruoze.bdp.dao.IDataSourceRepository;
import com.ruoze.bdp.entity.ClusterEntity;
import com.ruoze.bdp.entity.DataSourceEntity;
import com.ruoze.bdp.entity.DataSourceVo;
import com.ruoze.bdp.entity.datasource.DataSourceClusterVo;
import com.ruoze.bdp.entity.datasource.DataSourceRequest;
import com.ruoze.bdp.enums.DbType;
import com.ruoze.bdp.function.DataSourceFunction;
import com.ruoze.bdp.function.DataSourceFunctionBeanFactory;
import com.ruoze.bdp.service.DataSourceService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;


@Service
public class DataSourceServiceImpl implements DataSourceService {

    @Autowired
    private IDataSourceRepository repository;

    @Autowired
    private DataSourceFunctionBeanFactory factory;

    @Override
    public Page<DataSourceClusterVo> queryPage(DataSourceRequest request) {

        Integer pageNo = request.getPageNum() <= 0 ? 0 : request.getPageNum() - 1;   // 当前页码：前端从1开始，jpa从0开始，做个转换
        Integer pageSize =request.getPageSize() <= 10 ? 10 : request.getPageSize();  //每页数量

        //分页信息
        Pageable pageable = PageRequest.of(pageNo, pageSize, Sort.by(Sort.Direction.ASC, "id")); //页码：前端从1开始，jpa从0开始，做个转换

        //查询
        Page<DataSourceClusterVo> dataSourceClusterVoPage = repository.findDataSourceClusterVoPage(request, pageable);
        return dataSourceClusterVoPage;
    }


    @Override
    public void createNewDataSource(DataSourceVo newDataSource) {
        DataSourceEntity newDataSourceEntity = dataSourceVoToEntity(newDataSource);
        repository.save(newDataSourceEntity);
    }

    @Override
    public void replaceNewDataSource(DataSourceVo newDataSource, long id) {
        DataSourceEntity newDataSourceEntity = dataSourceVoToEntity(newDataSource);
        repository.findById(id).map(old -> {
            old.setClusterId(newDataSource.getClusterId());
            old.setName(newDataSource.getName());
            old.setNote(newDataSource.getNote());
            old.setConnectionParams(newDataSource.getConnectionParams());
            return repository.save(old);
        }).orElseGet(() -> repository.save(newDataSourceEntity));
    }

    @Override
    public void logicalDelDataSource(long id) {
        repository.logicalDeleteById(id);
    }

    @Override
    public void logicalBatchDelDataSource(List<Long> idList) {
        repository.logicalDeleteBatch(idList);
    }

    @Override
    public boolean connectTest(String type, String connectInfo) {
        DataSourceFunction dataSourceFunction = factory.getDataSourceFunction(type);
        return dataSourceFunction.connectTest(connectInfo);
    }

    @Override
    public List<String> queryNamesByType(String type) {
        return repository.findNamesByType(DbType.ofName(type.toUpperCase()));
    }

    private DataSourceEntity getDataSourceEntityById(Long id) {
        return repository.findById(id).orElseThrow(() -> new IllegalArgumentException("cannot find relation entity"));
    }

    private DataSourceEntity dataSourceVoToEntity(DataSourceVo vo) {
        DataSourceEntity dataSource = new DataSourceEntity();
        dataSource.setClusterId(vo.getClusterId());
        dataSource.setName(vo.getName().trim());
        dataSource.setNote(vo.getNote());
        dataSource.setCreatedUserId(vo.getUserId());
        dataSource.setCreatedUserName(vo.getUserName());
        dataSource.setType(DbType.ofName(vo.getType().toUpperCase()));
        dataSource.setConnectionParams(vo.getConnectionParams());
        return dataSource;
    }

    private DataSourceVo dataSourceEntityToVo(DataSourceEntity entity) {
        DataSourceVo vo = new DataSourceVo();
        vo.setId(entity.getId());
        vo.setType(entity.getType().getDesc());
        vo.setName(entity.getName());
        vo.setConnectionParams(entity.getConnectionParams());
        vo.setNote(entity.getNote());
        vo.setUserName(entity.getCreatedUserName());
        return vo;
    }
}
